/*
 * Copyright (C) 2008 Universidade Federal de Campina Grande
 *  
 * This file is part of OurGrid. 
 *
 * OurGrid is free software: you can redistribute it and/or modify it under the
 * terms of the GNU Lesser General Public License as published by the Free 
 * Software Foundation, either version 3 of the License, or (at your option) 
 * any later version. 
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT 
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
 * for more details. 
 * 
 * You should have received a copy of the GNU Lesser General Public License 
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 * 
 */
package org.ourgrid.common.executor;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

/**
 * This class creates a thread to read inputStream
 */
public class OutputCatcher implements Runnable {

	/** The input stream will be consumed */
	private InputStream stream;

	/** The buffered reader to get the bytes in the buffer when reading */
	private BufferedReader buffer;

	/** An string buffer to stored the read chars */
	private StringBuffer output = new StringBuffer();

	/** The thread will consume the stream */
	private Thread reader;


	/**
	 * Constructs the OutputCatcher object based on a stream to consume.
	 * 
	 * @param isr The stream will be consumed by the thread.
	 */
	public OutputCatcher( InputStream isr ) {

		/** The input stream of process */
		this.stream = isr;

		try {
			/** Just to check the stream availability */
			this.stream.available();

			/** Create the trhead to read the stream and close it */
			this.reader = new Thread( this, "OutputCatcher: Stream [" + isr + "]" );
			this.reader.start();

		} catch ( IOException e ) {
			System.err.println( "[Warning] The stream is closed." );
		}
	}


	/**
	 * The main method for the OutputCatcher thread. The idea is to consume the
	 * data generated by the stream and close it in the end.
	 */
	public void run( ) {

		String line = null;

		try {

			/** Create a buffer to read the stream */
			buffer = new BufferedReader( new InputStreamReader( this.stream ) );

			while ( ( line = buffer.readLine() ) != null ) {
				output.append( line + "\n" );

			}

		} catch ( IOException ioe ) {
			System.err.println( "[ERROR] " + getClass().getName() + ".run() - " + ioe.getMessage() );
		} finally {
			if ( buffer != null ) {
				try {
					buffer.close();
				} catch ( IOException e ) {

				}
			}
		}

	}


	/**
	 * This method provides access to the information read from stream.
	 * 
	 * @return What has been read.
	 * @throws InterruptedException If the thread has been interrupted
	 */
	public String getResult( ) throws InterruptedException {

		if ( reader != null ) {

			while ( reader.isAlive() ) {
				Thread.sleep( 100 );
			}
		}

		return output.toString();
	}

}
